﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.BIM;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class RiserDuctCreate : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				UIApplication application = commandData.Application;
				Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
				Document document = application.ActiveUIDocument.Document;
				UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
				List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(1);
				if (!YJKRevitTools.ViewCheck(activeUIDocument, viewTypes))
				{
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					transaction = new Transaction(document, "布置风管立管");
					transaction.Start();
					Selection selection = activeUIDocument.Selection;
					ISelectionFilter selectionFilter = new DuctFilter();
					Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择源风管");
					Duct ductOld = document.GetElement(reference) as Duct;
					List<string> levelUp = new List<string>();
					levelUp = YJKElementFilter.GetElementNameByClass(typeof(Level), document);
					List<string> ductSystemType = new List<string>();
					ductSystemType = YJKElementFilter.GetElementNameByClass(typeof(MechanicalSystemType), document);
					double zStart = 0.0;
					double zEnd = 0.0;
					MechanicalSystemType ductSystemType2 = null;
					DuctSize ductSize = null;
					for (;;)
					{
						RiserDuctCreateForm riserDuctCreateForm = new RiserDuctCreateForm(document, levelUp, ductSystemType, ductOld);
						DialogResult dialogResult = riserDuctCreateForm.ShowDialog();
						if (DialogResult.OK != dialogResult)
						{
							break;
						}
						zStart = riserDuctCreateForm.zStart;
						zEnd = riserDuctCreateForm.zEnd;
						ductSystemType2 = riserDuctCreateForm.ductSystemTypeRiser;
						ductSize = riserDuctCreateForm.ductSize;
						for (;;)
						{
							try
							{
								XYZ xyz = selection.PickPoint("请选择布置立管的点");
								double x = xyz.X;
								double y = xyz.Y;
								this.Draw(x, y, zStart, zEnd, document, ductOld, ductSize, ductSystemType2);
								continue;
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
							}
							break;
						}
						document.Regenerate();
					}
					transaction.Commit();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null && (int)transaction.GetStatus() != 3 && (int)transaction.GetStatus() != 2)
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private Duct NewDuct(Duct sourceDuct, XYZ startXYZ, XYZ endXYZ)
		{
			Duct duct = null;
			if (sourceDuct == null || startXYZ == null || endXYZ == null)
			{
				return null;
			}
			Document document = sourceDuct.Document;
			YJKDocument hydocument = new YJKDocument(document);
			foreach (ElementId elementId in ElementTransformUtils.CopyElement(document, sourceDuct.Id, new XYZ(0.0, 0.0, 0.0)))
			{
				duct = (hydocument.GetElement(elementId) as Duct);
			}
			document.Regenerate();
			if (duct != null)
			{
				((LocationCurve)duct.Location).Curve = YJKLineEx.YJKGetBound(new XYZ(0.0, 0.0, 0.0), new XYZ(1.0, 0.0, 0.0));
				document.Regenerate();
				YJKPiping<Duct> hypiping = new YJKPiping<Duct>(duct);
				hypiping.EndConnector.Connector.Origin = new XYZ(0.0, 0.0, 0.0);
				hypiping.StartConnector.Connector.Origin = new XYZ(1.0, 0.0, 0.0);
				document.Regenerate();
				Line curve = YJKLineEx.YJKGetBound(startXYZ, endXYZ);
				(duct.Location as LocationCurve).Curve = curve;
			}
			document.Regenerate();
			return duct;
		}

		private void Draw(double x, double y, double zStart, double zEnd, Autodesk.Revit.DB.Document document, Duct ductOld, DuctSize ductSize, MechanicalSystemType ductSystemType)
		{
			double projectElevation = document.ActiveView.GenLevel.ProjectElevation;
			Level genLevel = document.ActiveView.GenLevel;
			XYZ startXYZ = new XYZ(x, y, zStart + projectElevation);
			XYZ endXYZ = new XYZ(x, y, zEnd + projectElevation);
			Duct duct = this.NewDuct(ductOld, startXYZ, endXYZ);
			if (duct != null)
			{
				if (ductSize.Section == 0)
				{
					duct.GetParameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM).Set(ductSize.Diameter / 304.8);
				}
				else if (ductSize.Section == 1)
				{
					Parameter parameter = duct.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
					Parameter parameter2 = duct.GetParameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
					parameter.Set(ductSize.Width / 304.8);
					parameter2.Set(ductSize.Height / 304.8);
				}
				else if (ductSize.Section == 2)
				{
					Parameter parameter3 = duct.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
					Parameter parameter4 = duct.GetParameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
					parameter3.Set(ductSize.Width / 304.8);
					parameter4.Set(ductSize.Height / 304.8);
				}
				duct.GetParameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM).Set(ductSystemType.Id);
				duct.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM).Set(genLevel.Id);
				duct.LevelOffset = zStart;
			}
		}

		private Duct CopyPipe(Autodesk.Revit.DB.Document document, int section)
		{
			ConnectorProfileType connectorSharp = ConnectorSharp.Rect;
			if (section == 0)
			{
				connectorSharp = ConnectorSharp.Round;
			}
			else if (1 == section)
			{
				connectorSharp = ConnectorSharp.Rect;
			}
			else if (2 == section)
			{
				connectorSharp = ConnectorSharp.Oval;
			}
			else
			{
				connectorSharp = ConnectorSharp.Invalid;
			}
			List<Duct> ductBySection = YJKRevitTools.GetDuctBySection(document, connectorSharp);
			Duct result = null;
			foreach (Duct duct in ductBySection)
			{
				if (duct != null)
				{
					result = duct;
					break;
				}
			}
			return result;
		}
	}
}
